<template>
  <div>
    <div class="el-card__header">智慧运营助手</div>
    <div class="chat-container">
        <div class="chat-history" id="history">
          <div v-for="(msg, index) in messages" :key="index" class="message" :class="msg.type + '-message'">
            <div v-html="markdownText(msg.content)"></div>
          </div>
          <div v-if="loading" class="loading">
            <div class="dot-flashing"></div>
            <span style="color:#666;margin-left:10px">思考中...</span>
          </div>
        </div>
        <div class="input-container">
            <label for="fileInput">
                <img :src="uploadImg" class="input-icon" title="上传文档">
            </label>
            <input type="file" id="fileInput" hidden accept=".doc,.docx,.pdf,.xlsx">
            <input type="text" id="input" ref="input" placeholder="请上传文件或输入您的问题...">
            <img :src="sentImg" class="input-icon" @click="sendMessage" title="发送消息">
        </div>
        <div class="progress-container">
            <div class="progress-bar" id="uploadProgress"></div>
            <span class="progress-text" id="progressText">0%</span>
        </div>
    </div>
  </div>
</template>
<script>

import uploadpng from '@/assets/images/upload.png'
import sentpng from '@/assets/images/sent.png'
import 'highlight.js/styles/kimbie.light.css'
import markdownit from 'markdown-it'
import hljs from 'highlight.js';

// enable everything
const md = markdownit({
  html: true,
  linkify: true,
  typographer: true,
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return '<pre><code class="hljs">' +
               hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
               '</code></pre>';
      } catch (__) {}
    }

    return '<pre><code class="hljs">' + md.utils.escapeHtml(str) + '</code></pre>';
  }
})

export default {
  data() {
    return {
      question: '',
      answer: '',
      loading: false,
      messages: [{ type: 'bot', content: 
        `您好！欢迎使用业务中台智能运营助手，您的全能中台运营支持伙伴。 包含如下‌核心能力‌: <br/>
        ‌<b>‌1.智能问答‌：</b>提供模型数量与详情，如“罗列电网中台逻辑模型”。<br/>
        ‌<b>‌2.方案生成：</b>查询服务接口/使用指南，如“电网气象预警服务接口详情”。<br/>
        ‌<b>‌3.标准核查‌：</b>解答设计规范或提交文档审核，如“服务设计标准有哪些？”。<br/>
        ‌<b>‌4.技术支持‌：</b>解决调度组件/线上问题，如“熔断限流条件是什么？”。<br/>
        <b>‌5.其他问题：</b>其他场景问题的解答等……。<br/>
       `}],
      eventSource: '',
      uploadImg: uploadpng,
      sentImg: sentpng,
      fileName: ''
    }
  },
  mounted() {
    // 绑定回车键事件
    document.getElementById('input').onkeypress = (e) => {
      if (e.keyCode === 13) {
        this.sendMessage()
        return false
      }
    }

    // 绑定文件上传事件
    document.getElementById('fileInput').addEventListener('change', this.handleFileUpload)
  },
  methods: {
    markdownText(text) {
      this.loading = false
      if(typeof text ==='number'){
        return 'Token数：'+ text   
      }else{
        return md.render(text)
      }
    },
    sendMessage(obj,filename,that) {
      let me = that?that:this
      if (me.eventSource) {
        me.eventSource.close()
      }      

      me.loading = true
      let url = ''
      if(filename){
        me.messages.push({ type: 'user', content: '上传文件：'+filename })
        url="/base/smart/qa/chatstream?filename=" + encodeURIComponent(filename);//建立长连接的接口
      }else{
        // 使用Vue ref获取输入元素
        const input = me.$refs.input
        if (!input.value.trim()) return
        const question = input.value
        input.value = ''

        me.messages.push({ type: 'user', content: question })
        url="/base/smart/qa/chatstream?message=" + encodeURIComponent(question);//建立长连接的接口
        if(me.fileName){
          url += "&filename=" + encodeURIComponent(me.fileName)
        }
      }

      // 创建EventSource连接
      me.eventSource = new EventSource(url)

      let tokens  = 0
      // 处理消息接收
      me.eventSource.onmessage = (event) => {
        let data = JSON.parse(event.data)
        console.log("message is " + data);
        (data.output && data.output.text) ? console.log("text is " + data.output.text):'';
        
        //百炼平台
        if(data.output && data.output.text){
          let lastMessage = data.output.text
          me.messages.splice(me.messages.length-1,1,{ type: 'bot', content: lastMessage})
        }else{
          let models = data.usage && data.usage.models
          if(models){
            if(tokens == 0){
              me.messages.push({type: 'bot', content: tokens})
            }
            for (const item of models) {
              if(item.output_tokens){
                tokens = tokens + item.output_tokens
                console.log("tokens is " + tokens);
                me.messages.splice(me.messages.length-1,1,{ type: 'bot', content: tokens})
              }             
            }
          }
        }      
        
      }
      me.eventSource.onclose = function() {
        me.loading = false
        me.eventSource.close()
      }
      // 处理错误
      me.eventSource.onerror = (error) => {
        me.loading = false
        console.error('SSE连接错误:', error)
        me.eventSource.close()
        throw new Error('Connection error');
      }
    },
    handleFileUpload(e) {
      let me = this
      const file = e.target.files[0]
      if (!file) return

      // const progressBar = document.getElementById('uploadProgress')
      // const progressText = document.getElementById('progressText')
      // const progressContainer = document.querySelector('.progress-container')

      // progressBar.style.width = '0%'
      // progressText.textContent = '0%'
      // progressContainer.style.display = 'block'

      const formData = new FormData()
      formData.append('file', file)

      const xhr = new XMLHttpRequest()
      xhr.open('POST', '/base/smart/qa/upload')

      // xhr.upload.addEventListener('progress', (e) => {
      //   if (e.lengthComputable) {
      //     const percent = Math.round((e.loaded / e.total) * 100)
      //     progressBar.style.width = `${percent}%`
      //     progressText.textContent = `${percent}%`
      //   }
      // })

      xhr.onload = () => {
        // progressContainer.style.display = 'none'
        if (xhr.status >= 200 && xhr.status < 300) {
          const data = JSON.parse(xhr.responseText)
          console.log("response data is" ,data)
          me.fileName = data.filename
          me.messages.push({ type: 'user', content: data.filename })
          // this.showSystemMessage(data.error ? `文件上传失败：${data.error}` : "✅ 文件已上传分析完成")
          // if (data.filename) {
          //   me.sendMessage(null,data.filename,me)
          // }
        } else {
          this.showSystemMessage(`上传失败：${xhr.statusText}`)
        }
      }

      xhr.send(formData)
    },
    showSystemMessage(text) {
      this.messages.push({ type: 'system', content: text })
    },
    formatResponseText(text) {
      try {
        const jsonData = JSON.parse(text)
        return this.formatJSONtoHTML(jsonData)
      } catch (e) {
        return text
          .replace(/### (.*?)\n/g, '<h3>$1</h3>')
          .replace(/\n/g, '<br>')
      }
    },
    formatJSONtoHTML(data, level = 0) {
      if (typeof data !== 'object') return data
      const indent = level * 20
      let html = `<div class="json-view" style="margin-left:${indent}px">`

      if (Array.isArray(data)) {
        html += '<ul>'
        data.forEach(item => {
          html += `<li>${this.formatJSONtoHTML(item, level + 1)}</li>`
        })
        html += '</ul>'
      } else {
        html += '<ul>'
        Object.keys(data).forEach(key => {
          html += `<li>
            <span class="json-key">${key}</span>:
            ${this.formatJSONtoHTML(data[key], level + 1)}
          </li>`
        })
        html += '</ul>'
      }
      return html + '</div>'
    }
  }
}
</script>

<style scoped>
body {
    background: linear-gradient(135deg, #f0f9ff, #e6f4ff);
    font-family: 'Microsoft Yahei', sans-serif;
    margin: 0;
    min-height: 100vh;
}



.chat-container {
    max-width: 900px;
    margin: 20px auto;
    background: white;
    border-radius: 15px;
    box-shadow: 0 5px 25px rgba(0, 120, 255, 0.1);
    overflow: hidden;
    position: relative; /* 新增定位上下文 */
}



.progress-container {
    max-width: 900px;
    margin: 0 auto;
    position: relative;
    width: 100%;
    height: 4px;
    background: #e0e0e0;
    border-radius: 2px;
    margin-top: 10px;
    display: none;
}

.header {
    background: linear-gradient(135deg, #007bff, #0056b3);
    color: white;
    padding: 20px 30px;
    font-size: 24px;
    font-weight: 500;
}

.chat-history {
    height: 70vh;
    padding: 20px;
    overflow-y: auto;
    overflow-x: hidden;
    background: #f8fcff;
}

.message {
    margin: 15px 0;
    padding: 12px 20px;
    border-radius: 12px;
    max-width: 80%;
    animation: fadeIn 0.3s;
    line-height: 1.6;
}

/* 修改响应框样式 */
.response-box {
    padding: 12px 15px;  /* 减少内边距 */
    margin: 8px 0;       /* 减少外边距 */
}

/* 优化消息排版 */
.bot-message {
    padding: 0 10px;
    margin: 5px 0;
}

/* 去除标题左侧留白 */
.bot-message h3 {
    border-left: none;
    padding-left: 0;
    margin-top: 10px;
}

/* 添加表格样式 */
.bot-message table {
    border-collapse: collapse;
    width: 100%;
    margin: 10px 0;
}

.bot-message th, 
.bot-message td {
    border: 1px solid #827d7d;
    padding: 8px;
    text-align: left;
}

.bot-message th {
    background-color: #827d7d;
    font-weight: bold;
}

.bot-message tr:nth-child(even) {
    background-color: #827d7d;
}

/* 加载动画 */
.dot-flashing {
    position: relative;
    width: 10px;
    height: 10px;
    border-radius: 5px;
    background-color: #007bff;
    animation: dotFlashing 1s infinite linear;
}

@keyframes dotFlashing {
    0% { opacity: 0.2 }
    50% { opacity: 1 }
    100% { opacity: 0.2 }
}

.loading {
    display: flex;
    align-items: center;
    padding: 10px;
}

.input-box {
    display: flex;
    gap: 10px;
    padding: 20px;
    background: white;
    border-top: 1px solid #e0e0e0;
}

.upload-btn {
    width: 18%;
    min-width: 100px;
    margin-right: 0;
}

/* 新增底部输入栏样式 */
.chat-container {
    max-width: 900px;
    margin: 20px auto;
    /* 保持原有样式不变 */
}

/* 修改输入容器样式 */
.input-container {
    position: fixed;
    bottom: 20px;
    width: 100%;
    max-width: 900px; /* 与主容器同步 */
    background: rgba(255,255,255,0.9);
    border-radius: 30px;
    padding: 10px 10px;
    box-shadow: 0 5px 15px rgba(0,0,0,0.1);
    display: flex;
    gap: 10px;
}

/* 新增媒体查询适配小屏幕 */
@media (max-width: 840px) {
    .input-container {
        width: calc(100% - 40px); /* 左右各留20px边距 */
        left: 20px;
        transform: none;
    }
}
.input-icon {
    width: 40px;
    height: 40px;
    cursor: pointer;
    transition: all 0.3s;
}

.input-icon:hover {
    transform: scale(1.1);
}

#input {
    flex: 1;
    border: none;
    background: transparent;
    font-size: 16px;
    padding: 8px 15px;
}

/* 消息格式优化 */
.bot-message {
    /* white-space: pre-wrap; */
    line-height: 1.5;
}

.bot-message h3 {
    color: #007bff;
    font-size: 1.2em;
    margin: 15px 0 10px;
    border-left: 4px solid #007bff;
    padding-left: 10px;
}

.bot-message p {
    margin: 8px 0;
}

/* 调整消息间距 */
.message {
    margin: 10px 0;
}

/* 移除logo相关样式 */
.header {
    padding: 20px 30px;
    text-align: center;
}

.upload-btn:hover {
    background: #218838 !important;
}

#fileInput {
    display: none;
}

/* 进度条样式 */
.progress-container {
    position: relative;
    width: 100%;
    height: 4px;
    background: #e0e0e0;
    border-radius: 2px;
    margin-top: 10px;
    display: none;
}

.progress-bar {
    height: 100%;
    background: #007bff;
    border-radius: 2px;
    transition: width 0.3s ease;
}

.progress-text {
    position: absolute;
    right: 0;
    top: -20px;
    font-size: 12px;
    color: #666;
}

/* JSON样式 */
.json-view {
    font-family: Consolas, monospace;
    color: #333;
}

.json-key {
    color: #007bff;
    font-weight: 600;
}

.json-view ul {
    list-style: none;
    padding-left: 15px;
}

.json-view li {
    margin: 5px 0;
    padding-left: 10px;
    border-left: 2px solid #eee;
}

/* 用户消息样式 */
.message.user-message {
    background: #007bff;
    color: white;
    border-radius: 15px 15px 0 15px;
    margin-left: auto;
    margin-right: 10px;
    position: relative;
    max-width: 80%;
}

/* 机器人消息样式 */
.message.bot-message {
    background: #f1f3f5;
    color: #333;
    border-radius: 15px 15px 15px 0;
    margin-right: auto;
    margin-left: 10px;
    position: relative;
    max-width: 80%;
    border: 1px solid #dee2e6;
}

/* 消息图标定位 */
.message::before {
    position: absolute;
    top: -5px;
    font-size: 24px;
}

.user-message::before {
    content: "👤";
    right: -35px;
}

.bot-message::before {
    content: "";
    left: -32px;
    background-image: url("~@/assets/images/botai.jpg");
    width: 32px;
    height: 32px;
    background-size: contain;
    background-repeat: no-repeat;
}


.bot-message th, 
.bot-message td {
    border: 1px solid #ddd;
    padding: 8px;
    text-align: left;
}

.bot-message th {
    background-color: #f2f2f2;
    font-weight: bold;
}

.bot-message tr:nth-child(even) {
    background-color: #f9f9f9;
}

/* 添加表格样式 */
.bot-message >>> table {
    border-collapse: collapse;
    width: 100%;
    margin: 10px 0;
}

.bot-message >>> th, 
.bot-message >>> td {
    border: 1px solid #ddd;
    padding: 8px;
    text-align: left;
}

.bot-message >>> th {
    background-color: #e9efe9;
    font-weight: bold;
}

.bot-message >>> tr:nth-child(even) {
    background-color: #ecedf0;
}
</style>
